package com.googlecode.jwsm.security.caching;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Properties;

import com.googlecode.jwsm.security.Privilege;
import com.googlecode.jwsm.security.User;

public class CachedUser implements User {
	private User user;
	private HashMap cache;
	private long timeout;
	
	public CachedUser(User user, long timeout) {
		this.user = user;
		this.timeout = timeout;
		cache = new HashMap();
	}

	public Privilege[] getPrivileges() {
		CachedObject cached = (CachedObject) cache.get("Privileges");
		if (cached == null) {
			cached = new CachedObject(user.getPrivileges(), timeout);
			cache.put("Privileges", cached);
		} else if (cached.isExpired())
			cached.set(user.getPrivileges());
		return (Privilege[]) (Privilege[]) cached.get();
	}

	public Properties getProperties(String application) {
		String key;
		if (application == null)
			key = "Properties";
		else
			key = "Properties:" + application;
		CachedObject cached = (CachedObject) cache.get(key);
		if (cached == null) {
			cached = new CachedObject(user.getProperties(application), timeout);
			cache.put(key, cached);
		} else if (cached.isExpired())
			cached.set(user.getProperties(application));
		return (Properties) cached.get();
	}

	public Object getProperty(String name) {
		CachedObject cached;
		if (cache.containsKey("Properties")) {
			cached = (CachedObject) cache.get("Properties");
			if (!cached.isExpired())
				return cached.get();
		}
		cached = (CachedObject) cache.get("Property:" + name);
		if (cached == null) {
			cached = new CachedObject(user.getProperty(name), timeout);
			cache.put("Property:" + name, cached);
		} else if (cached.isExpired())
			cached.set(user.getProperty(name));
		return cached.get();
	}

	public String[] getPropertyNames(String application) {
		String key;
		if (application == null)
			key = "PropertyNames";
		else
			key = "PropertyNames:" + application;
		CachedObject cached = (CachedObject) cache.get(key);
		if (cached == null) {
			cached = new CachedObject(user.getPropertyNames(application),
					timeout);
			cache.put(key, cached);
		} else if (cached.isExpired())
			cached.set(user.getPropertyNames(application));
		return (String[]) (String[]) cached.get();
	}

	public String getUsername() {
		return user.getUsername();
	}

	public boolean hasPrivilege(String privilegeName) {
		Privilege privs[] = getPrivileges();
		for (int i = 0; i < privs.length; i++)
			if (privs[i].getName().equals(privilegeName))
				return true;

		return false;
	}

	public boolean isAuthorized(String url) {
		CachedObject cached = (CachedObject) cache.get("Authorized:" + url);
		if (cached == null) {
			cached = new CachedObject(new Boolean(user.isAuthorized(url)),
					timeout);
			cache.put("Authorized:" + url, cached);
		} else if (cached.isExpired())
			cached.set(new Boolean(user.isAuthorized(url)));
		return ((Boolean) cached.get()).booleanValue();
	}

	public void setProperty(String name, Serializable value) {
		user.setProperty(name, value);
		String key = "Property:" + name;
		CachedObject cached = new CachedObject(value, timeout);
		cache.put(key, cached);
	}

	public String getName() {
		return user.getName();
	}
}
